package java_thinking.unit_10._10_8;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description : 控制事件
 * @author: cww
 * @DateTime: 2019-03-13 22:44
 */
abstract class Event {
    private long eventTime;
    protected final long delayTime;
    public Event(long delayTime){
        this.delayTime = delayTime;
        start();
    }

    /**
     * 生成事件的触发事件
     */
    public void start(){
        eventTime = System.nanoTime() + delayTime;
    }

    /**
     * 检测是否到达时间
     *
     * @return
     */
    public boolean ready(){
        return System.nanoTime() >= eventTime;
    }

    /**
     * 具体操作由子类实现
     */
    public abstract void action();
}


class Controller{
    private List<Event> events = new ArrayList<Event>();
    public void addEvent(Event event){
        events.add(event);
    }
    public void run(){
        /**
         * 遍历events，只要event是准备好的，循环执行并清理
         */
        while (events.size()>0){
            for (Event event:new ArrayList<Event>(events)){
                if (event.ready()){
                    System.out.println(event);
                    event.action();
                    events.remove(event);
                }
            }
        }
    }
}

/**
 * 温室大棚案例：控制灯光、水、温度掉节器的开关
 * 灯光、水、铃都属于GreenHouse，既能访问Controller内部的方法与对象，又能在内部类继承Event，相当于两个类功能
 * 的混合应用
 */
class GreenHouseControls extends Controller{
    private boolean light = false;
    public class LightOn extends Event{

        public LightOn(long delayTime){
            super(delayTime);
        }
        /**
         * 具体操作由子类实现
         */
        @Override
        public void action() {
            light = true;
        }
        @Override
        public String toString(){
            return "Light is on";
        }
    }

    public class LightOff extends Event {

        public LightOff(long delayTime){
            super(delayTime);
        }
        /**
         * 具体操作由子类实现
         */
        @Override
        public void action() {
            light = false;
        }
        @Override
        public String toString(){
            return "Light is off";
        }
    }

    private boolean water = false;
    public class WaterOn extends Event {
        public WaterOn(long delayTime) {
            super(delayTime);
        }

        /**
         * 具体操作由子类实现
         */
        @Override
        public void action() {
            water =true;
        }
        @Override
        public String toString(){
            return "Water is on";
        }
    }

    public class WaterOff extends Event {
        public WaterOff(long delayTime) {
            super(delayTime);
        }

        /**
         * 具体操作由子类实现
         */
        @Override
        public void action() {
            water =false;
        }
        @Override
        public String toString(){
            return "Water is off";
        }
    }

    public class Bell extends Event {
        public Bell(long delayTime){
            super(delayTime);
        }

        /**
         * 具体操作由子类实现
         */
        @Override
        public void action() {
            /**
             * 实现再次响铃功能
             */
            addEvent(new Bell(delayTime));
        }
        @Override
        public String toString(){
            return "Bing!";
        }
    }

    public class Restart extends Event {
        private Event[] events;

        /**
         * 初始化组装事件列表
         * @param delayTime
         * @param events
         */
        public Restart(long delayTime,Event[] events){
            super(delayTime);
            this.events = events;
            for (Event e:events){
                addEvent(e);
            }
        }
        /**
         * 具体操作由子类实现
         */
        @Override
        public void action() {
            for (Event e:events){
                e.start();
                addEvent(e);
            }
            start();
            addEvent(this);
        }
        @Override
        public String toString(){
            return "Restarting system";
        }
    }
    public static class Terminate extends Event {

        public Terminate(long delayTime){
            super(delayTime);
        }
        /**
         * 具体操作由子类实现
         */
        @Override
        public void action() {
            System.exit(0);
        }
        @Override
        public String toString(){
            return "Terminating";
        }
    }
}

class GreenhouseController {
    public static void main(String[] args) {
        GreenHouseControls gc = new GreenHouseControls();
        gc.addEvent(gc.new Bell(900));

        Event[] events = {
          gc.new LightOn(200),
          gc.new LightOff(400),
          gc.new WaterOn(600),
          gc.new WaterOff(800),
        };
        gc.addEvent(gc.new Restart(2000,events));

        if (true){
            gc.addEvent(new GreenHouseControls.Terminate(10000));
        }
        gc.run();
    }
}